请求级别的；
在 controller 和 service 中获取：
this.ctx.request,
this.ctx.response;

当 post 请求时，参数在：
this.ctx.request.body 中；
假如有post请求：{"title": "controller", "content": "what is controller"}
  this.ctx.request.body.title, this.ctx.request.body.content 即可获取。


this.ctx.query === this.ctx.request.query;
this.ctx.body === this.ctx.response.body;


请求参数的获取
GET /posts?category=egg&language=node
ctx.query.category,
ctx.query.language;
当同名的参数有多个时，只能获取到第一个，后面的都被忽略；
而 ctx.queries 则会获取所有的参数，同名参数的值放到一个数组内；而且，即使只有一个值，也是放在一个数组内的！


router 中的路由参数：
路由：
  app.get('/projects/:projectId/app/:appId', 'app.listApp');
访问时的 url：GET /projects/1/app/2
Controller、Service 中获取：
  this.ctx.params.projectId;
  this.ctx.params.appId;



请求头信息
ctx.request.header, ctx.request.headers, ctx.header, ctx.headers 四个是等价的，都是获取整个 header 对象；
ctx.get(headername); ctx.request.get(headername); 如果不存在，返回空字符串；会自动处理大小写；
还能用 ctx.headers[headername]; 但不推荐；



响应状态码
this.ctx.status = 200;

响应体
this.ctx.body; === this.ctx.response.body;
this.ctx.body = {
  name: 'egg',
  category: 'framework',
  language: 'Node.js',
};// Content-Type 为 application/json
this.ctx.body = '<html><h1>Hello</h1></html>';// Content-Type 为 text/html
// 流式响应体
  const result = await this.ctx.curl(url, {
    streaming: true,
  });
  this.ctx.set(result.header);
  // result.res 是一个 stream
  this.ctx.body = result.res;

响应头
this.ctx.set(headername, value);

重定向
ctx.redirect(url) 如果不在配置的白名单域名内，则禁止跳转。
ctx.unsafeRedirect(url) 不判断域名，直接跳转，一般不建议使用，明确了解可能带来的风险后使用。
// config/config.default.js
exports.security = {
  domainWhiteList:['.domain.com'],  // 安全白名单，以 . 开头
};
若用户没有配置 domainWhiteList 或者 domainWhiteList数组内为空，则默认会对所有跳转请求放行，即等同于ctx.unsafeRedirect(url)
